﻿using ChatMsg;
using CopyMsgToTxt.Enum;
using CopyMsgToTxt.Helper;
using CopyMsgToTxt.ParseModel;
using Ice;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsInput;
using WindowsInput.Native;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using Exception = System.Exception;
using Message = CopyMsgToTxt.ParseModel.Message;
using Process = System.Diagnostics.Process;

namespace CopyMsgToTxt
{
    public partial class Form1 : Form
    {
        //private const string ReceiverColor = "#F3F5FA";//接收消息颜色
        //private const string SendColor = "#4A70FF";//接收消息颜色
        //private const string NoMessageColor = "#FFFFFF";//接收消息颜色

        private const int ReceiverColor = 16446963;//接收消息颜色
        private const int SendColor = 16740426;//发送消息颜色（蓝）
        private const int NoMessageColor = 16777215;//背景色（纯白）
        public Form1()
        {
            InitializeComponent();
        }

        #region 旧实现（模拟复制动作）

        private void Form1_Load(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(CapturePoint));
            t.IsBackground = true;
            t.Start();
        }
        private void CapturePoint()
        {
            var timer = new System.Timers.Timer();
            timer.Interval = 5000;
            timer.Enabled = true;
            timer.AutoReset = true;//设置是执行一次（false）还是一直执行(true)；  
            timer.Elapsed += async (o, a) =>
            {
                // 记录更新开始时间
                DateTime startTime = DateTime.Now;
                AppLog.WriteInfo("更新开始时间：" + startTime.ToString("yyyy/MM/dd HH:mm:ss.fff"));

                // 执行长时间任务
                await ReceiveInfoAsync();

                // 记录更新结束时间
                DateTime endTime = DateTime.Now;
                AppLog.WriteInfo("更新结束时间：" + endTime.ToString("yyyy/MM/dd HH:mm:ss.fff"));

                // 计算时间差
                TimeSpan elapsedTime = endTime - startTime;
                AppLog.WriteInfo(string.Format("更新花费时间：{0} 毫秒", elapsedTime.TotalMilliseconds));
            };

            timer.Start();
        }
        //private void CapturePoint()
        //{
        //    var timer = new System.Timers.Timer();
        //    timer.Interval = 5000;
        //    timer.Enabled = true;
        //    timer.AutoReset = true;//设置是执行一次（false）还是一直执行(true)；  
        //    timer.Elapsed += async (o, a) =>
        //    {
        //        // 记录更新开始时间
        //        DateTime startTime = DateTime.Now;
        //        AppLog.WriteInfo("更新开始时间：" + startTime.ToString("yyyy/MM/dd HH:mm:ss.fff"));

        //        // 执行长时间任务
        //        await ReceiveInfoAsync();

        //        // 记录更新结束时间
        //        DateTime endTime = DateTime.Now;
        //        AppLog.WriteInfo("更新结束时间：" + endTime.ToString("yyyy/MM/dd HH:mm:ss.fff"));

        //        // 计算时间差
        //        TimeSpan elapsedTime = endTime - startTime;
        //        AppLog.WriteInfo(string.Format("更新花费时间：{0} 毫秒", elapsedTime.TotalMilliseconds));
        //    };

        //    timer.Start();
        //}

        private async Task GetChatMessageFromWindowAsync_Old(string chatterName)
        {
            try
            {
                // 异步获取窗口左上角坐标
                Point windowPoint = await Task.Run(() => WindowHelper.GetWindowTopLeftCorner("QiDian", chatterName));
                IntPtr handleQD = WindowFromPoint(windowPoint);
                // 将窗口置于前台
                //SetForegroundWindow(handleQD);

                // 强制刷新窗口
                //InvalidateRect(handleQD, IntPtr.Zero, true);
                if (windowPoint.X == 0 && windowPoint.Y == 0)
                {
                    AppLog.WriteInfo($"窗体 {chatterName} 在原点（0,0）");
                    // 窗体在原点（0,0）
                }
                else if (windowPoint.X.ToString().Contains("-32000"))
                {
                    AppLog.WriteInfo($"窗体 {chatterName} 没开");
                    // 窗体没开
                }
                else
                {
                    await Task.Run(() => GetSendMessage(windowPoint, handleQD, chatterName));
                    await Task.Run(() => GetReceiveMessage(windowPoint, handleQD, chatterName));
                }
            }
            catch (System.Exception ex)
            {
                AppLog.WriteError($"{ex.Message} CheckMsgFromWindow for {chatterName}");
            }
        }

        // 定时器间隔（毫秒）
        private const int TimerInterval = 5000; // 5秒




        private Task _infoTask;
        string windowTitle = "钟长明";

        private IntPtr _currentWindowHandle;
   
        private async Task ReceiveInfoAsync()
        {
            List<Task> tasks = new List<Task>();

            foreach (var chatName in ChatName)
            {
                await GetChatMessageFromWindowAsync(chatName);
            }

            await Task.WhenAll(tasks);
        }

      

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase);
        List<string> ChatName = new List<string>() { "钟长明", "谷苏", "王旭" };
        

        Dictionary<string, List<Point>> savedPoints = new Dictionary<string, List<Point>>(); //用于保存一个中介及其聊天记录的所在位置

        //窗口相关参数（都是以窗口左上角那点为基准）
        private int sendLeft = 446;//发送方向右偏移540单位
        private int sendTop = 75;//发送方向下偏移90单位
        private int receiveLeft = 58;//发送方向下偏移90单位
        private int receiveTop = 75;//发送方向下偏移90单位

        private int step = 6; // 步长（上下）
        private int windowHeight = 379;//只是聊天窗体的高度
        private string GetSendMessage(Point windowPoint, IntPtr hwnd, string chatName)
        {
            try
            {
                AppLog.WriteInfo($"{chatName}--窗体左上角为：x:{windowPoint.X},y:{windowPoint.Y}！");
                int sendMessageCount = 0;
                int receiveMessageCount = 0;
                int searchSendStartX = windowPoint.X + sendLeft; // 发送方起始搜索点的 X 坐标
                int searchSendStartY = windowPoint.Y + sendTop; // 发送方起始搜索点的 Y 坐标
                int searchReceiveStartX = windowPoint.X + receiveLeft; // 发送方起始搜索点的 X 坐标
                int searchReceiveStartY = windowPoint.Y + receiveTop; // 发送方起始搜索点的 Y 坐标
                bool inMessage = false; // 是否在消息中的标志
                bool isMessageStart = false; // 遇到第一个蓝色标记才说明正式捕获消息了
                bool wasInMessage = false; // 用于跟踪上一个状态是否在消息中
                List<WindowMessageInfo> sendMessages = new List<WindowMessageInfo>();
                List<Point> points = new List<Point>();
                Point temp;
                int pixelInt = 0;
                for (int y = searchSendStartY; y < windowPoint.Y + windowHeight; y += step)
                {

                    temp = new Point(searchSendStartX, y);
                    lock (lock1)
                    {
                        pixelInt = GetColorRGB(temp);
                        AppLog.WriteInfo($"{chatName}--记录发送方坐标：x:{temp.X},y:{temp.Y}，颜色：{pixelInt}");
                    }



                    if (!isMessageStart)
                    {
                        if (pixelInt == SendColor)
                        {
                            isMessageStart = true;
                            points.Add(temp);
                            //AppLog.WriteInfo("发送者第一次：坐标--"+temp.X+","+temp.Y);
                            inMessage = true; // 开始消息标志
                        }
                        else
                        {
                            continue;
                        }
                    }

                    //到这了说明找到第一条蓝底的气泡消息了
                    if (isMessageStart)
                    {
                        if (pixelInt == NoMessageColor)
                        {
                            if (inMessage)
                            {
                                //y -= 10;
                                inMessage = false; // 结束当前消息标志
                                wasInMessage = true;
                                sendMessageCount++;
                                sendMessages.Add(new WindowMessageInfo
                                {
                                    LocX = temp.X,
                                    LocY = y - 10,
                                    Type = "S",
                                    RecordTime = DateTime.Now
                                });
                                AppLog.WriteInfo("发送人" + chatName + "气泡：坐标--" + temp.X + "," + (y - 10));
                                y += 5;
                                continue;
                            }
                            else if (wasInMessage)
                            {
                                // 如果刚刚从消息状态中出来，说明已经找到完整的消息
                                continue;
                            }
                        }
                        else if (pixelInt == SendColor)
                        {
                            inMessage = true;
                            wasInMessage = false;
                            y += 5;
                            //AppLog.WriteInfo("发送者后续：坐标--" + temp.X + "," + temp.Y);
                            continue;
                        }

                        if (inMessage)
                        {
                            //CopySimulator.SimulateRightClickAndCopy(temp, hwnd);
                        }
                    }
                }
                AppLog.WriteInfo("聊天人" + chatName + $"共找到{sendMessageCount}个发送方聊天气泡");
                //this.Invoke((Action)(() =>
                //{
                //    this.richTextBox1.Text = string.Join("\r\n", points);
                //}));
                return JsonConvert.SerializeObject(sendMessages);
            }
            catch (Exception ex)
            {
                AppLog.WriteError("聊天人" + chatName + ex.Message + "抓取像素点异常");
            }
            return null;
        }


        private string GetReceiveMessage(Point windowPoint, IntPtr hwnd, string chatName)
        {
            try
            {
                AppLog.WriteInfo($"{chatName}--窗体左上角为：x:{windowPoint.X},y:{windowPoint.Y}！");
                int sendMessageCount = 0;
                int receiveMessageCount = 0;
                int searchSendStartX = windowPoint.X + sendLeft; // 发送方起始搜索点的 X 坐标
                int searchSendStartY = windowPoint.Y + sendTop; // 发送方起始搜索点的 Y 坐标
                int searchReceiveStartX = windowPoint.X + receiveLeft; // 发送方起始搜索点的 X 坐标
                int searchReceiveStartY = windowPoint.Y + receiveTop; // 发送方起始搜索点的 Y 坐标
                bool inMessage = false; // 是否在消息中的标志
                bool isMessageStart = false; // 遇到第一个蓝色标记才说明正式捕获消息了
                bool wasInMessage = false; // 用于跟踪上一个状态是否在消息中
                List<WindowMessageInfo> receiveMessages = new List<WindowMessageInfo>();
                List<Point> points = new List<Point>();
                Point temp;
                int pixelInt = 0;
                for (int y = searchReceiveStartY; y < windowPoint.Y + windowHeight; y += step)
                {

                    temp = new Point(searchReceiveStartX, y);
                    lock (lock1)
                    {
                        pixelInt = GetColorRGB(temp);
                        AppLog.WriteInfo($"{chatName}--记录接收方坐标：x:{temp.X},y:{temp.Y}，颜色：{pixelInt}");
                    }



                    if (!isMessageStart)
                    {
                        if (pixelInt == ReceiverColor)
                        {
                            isMessageStart = true;
                            points.Add(temp);
                            //AppLog.WriteInfo("发送者第一次：坐标--"+temp.X+","+temp.Y);
                            inMessage = true; // 开始消息标志
                        }
                        else
                        {
                            continue;
                        }
                    }

                    //到这了说明找到第一条蓝底的气泡消息了
                    if (isMessageStart)
                    {
                        if (pixelInt == NoMessageColor)
                        {
                            if (inMessage)
                            {
                                //y -= 10;
                                inMessage = false; // 结束当前消息标志
                                wasInMessage = true;
                                receiveMessageCount++;
                                receiveMessages.Add(new WindowMessageInfo
                                {
                                    LocX = temp.X,
                                    LocY = y - 10,
                                    Type = "R",
                                    RecordTime = DateTime.Now
                                });
                                AppLog.WriteInfo("接收人" + chatName + "气泡：坐标--" + temp.X + "," + (y - 10));
                                y += 5;
                                continue;
                            }
                            else if (wasInMessage)
                            {
                                // 如果刚刚从消息状态中出来，说明已经找到完整的消息
                                continue;
                            }
                        }
                        else if (pixelInt == ReceiverColor)
                        {
                            inMessage = true;
                            wasInMessage = false;
                            y += 5;
                            //AppLog.WriteInfo("发送者后续：坐标--" + temp.X + "," + temp.Y);
                            continue;
                        }

                        if (inMessage)
                        {
                            //CopySimulator.SimulateRightClickAndCopy(temp, hwnd);
                        }
                    }
                }
                AppLog.WriteInfo("聊天人" + chatName + $"共找到{receiveMessageCount}个接收方聊天气泡");
                //this.Invoke((Action)(() =>
                //{
                //    this.richTextBox1.Text = string.Join("\r\n", points);
                //}));
                return JsonConvert.SerializeObject(receiveMessages);
            }
            catch (Exception ex)
            {
                AppLog.WriteError("聊天人" + chatName + ex.Message + "抓取像素点异常");
            }
            return null;
        }
        private object lock1 = new object();
        private int GetColorRGB(Point p)
        {
            IntPtr hdc = GetDC(new IntPtr(0));//取到设备场景(0就是全屏的设备场景) 
            int color = GetPixel(hdc, p);//取指定点颜色 
            ReleaseDC(IntPtr.Zero, hdc);
            return color;

        }
        [DllImport("gdi32.dll")]//取指定点颜色 
        private static extern int GetPixel(IntPtr hdc, Point p);
        [DllImport("user32.dll")]
        private static extern IntPtr GetDC(IntPtr hWnd);

        // P/Invoke to release the device context
        [DllImport("user32.dll")]
        private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

        // P/Invoke to get the color of a pixel at a specific coordinate
        [DllImport("gdi32.dll")]
        private static extern uint GetPixel(IntPtr hDC, int nXPos, int nYPos);

        [DllImport("User32.dll")]
        private static extern IntPtr WindowFromPoint(Point p);



        public void AddMessage(string message)
        {
            if (this.richTextBox1.InvokeRequired)
            {
                this.Invoke(new Action<string>(AddMessage), message);
            }
            else
            {
                this.richTextBox1.AppendText(message + Environment.NewLine);
            }
        }

        private string GetProcessName(IntPtr handle)
        {
            uint processId;
            ProcessInfoHelper.GetWindowThreadProcessId(handle, out processId);
            Process process = Process.GetProcessById((int)processId);
            return process.ProcessName;
        }

        #region 模拟鼠标右键复制
        [DllImport("user32.dll")]
        private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, IntPtr dwExtraInfo);

        private const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
        private const uint MOUSEEVENTF_RIGHTUP = 0x0010;

        private void SimulateRightClickAndCopy(Point location)
        {
            IntPtr hWnd = GetForegroundWindow();

            // 发送右键点击消息
            SendMessage(hWnd, WM_RBUTTONDOWN, IntPtr.Zero, (IntPtr)(location.Y << 16 | location.X));
            Thread.Sleep(100); // 添加一个小延迟，以便更好地模拟
            SendMessage(hWnd, WM_RBUTTONUP, IntPtr.Zero, (IntPtr)(location.Y << 16 | location.X));
            Thread.Sleep(100); // 添加一个小延迟，以便更好地模拟

            // 获取弹出菜单的句柄
            IntPtr hMenu = SendMessage(hWnd, WM_SYSCOMMAND, (IntPtr)0x313, IntPtr.Zero); // SC_MOUSEMENU

            // 获取菜单项数目
            int count = GetMenuItemCount(hMenu);

            // 找到"复制"菜单项并发送消息
            for (int i = 0; i < count; i++)
            {
                IntPtr hSubMenu = GetSubMenu(hMenu, i);
                uint menuItemID = GetMenuItemID(hSubMenu, i);

                if (menuItemID == IDM_COPY)
                {
                    SendMessage(hWnd, WM_COMMAND, (IntPtr)IDM_COPY, IntPtr.Zero);
                    break;
                }
            }
        }

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        private static extern IntPtr GetSubMenu(IntPtr hMenu, int nPos);

        [DllImport("user32.dll")]
        private static extern int GetMenuItemCount(IntPtr hMenu);

        [DllImport("user32.dll")]
        private static extern uint GetMenuItemID(IntPtr hMenu, int nPos);

        private const int WM_RBUTTONDOWN = 0x0204;
        private const int WM_RBUTTONUP = 0x0205;

        private const int WM_COMMAND = 0x0112;
        private const int WM_SYSCOMMAND = 0x112;

        private const int MF_BYCOMMAND = 0x00000000;

        private const int IDM_COPY = 0x0002; // "复制"菜单项的ID
        #endregion



        private async void button1_Click(object sender, EventArgs e)
        {
            Communicator communicator = null;


            try
            {
                // 初始化 Ice 通信
                communicator = Ice.Util.initialize();

                // 创建代理并连接到 Ice 服务端
                var proxy = communicator.stringToProxy("SendMessageToPy:default -p 18888");
                var server = SendMessageToPyPrxHelper.checkedCast(proxy);

            
                if (server == null)
                {
                    throw new ApplicationException("Invalid proxy");
                }

                // 调用 Ice 服务端的方法
                string chatName = this.comboBox1.Text;
                try
                {

                    // 异步获取窗口左上角坐标
                    Point windowPoint = await Task.Run(() => WindowHelper.GetWindowTopLeftCorner("QiDian", chatName));
                    IntPtr handleQD = WindowFromPoint(windowPoint);
                    // 将窗口置于前台
                    //SetForegroundWindow(handleQD);

                    // 强制刷新窗口
                    //InvalidateRect(handleQD, IntPtr.Zero, true);
                    if (windowPoint.X == 0 && windowPoint.Y == 0)
                    {
                        AppLog.WriteInfo($"窗体 {chatName} 在原点（0,0）");
                        // 窗体在原点（0,0）
                    }
                    else if (windowPoint.X.ToString().Contains("-32000"))
                    {
                        AppLog.WriteInfo($"窗体 {chatName} 没开");
                        // 窗体没开
                    }
                    else
                    {
                        string msg =  await Task.Run(() => GetReceiveMessage(windowPoint, handleQD, chatName));
                        server.SendChatMsg(msg);
                        string msg2 = await Task.Run(() => GetSendMessage(windowPoint, handleQD, chatName));
                        server.SendChatMsg(msg2);
                    }
                }
                catch (System.Exception ex)
                {
                    AppLog.WriteError($"{ex.Message} CheckMsgFromWindow for {chatName}");
                }
                //Console.WriteLine("Response from server: " + response);
            }
            finally
            {
                // 清理资源
                if (communicator != null)
                {
                    communicator.destroy();
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Communicator communicator = null;

            // 初始化 Ice 通信
            communicator = Ice.Util.initialize();

            // 创建代理并连接到 Ice 服务端
            var proxy = communicator.stringToProxy("SendMessageToPy:default -p 18888");
            var server = SendMessageToPyPrxHelper.checkedCast(proxy);

            server.SendChatMsg("1111");
        }

        #endregion


        #region 新实现（2024.06.16——模拟全选复制）
        private const int KEYEVENTF_KEYUP = 0x0002;
        private const int VK_CONTROL = 0x11;
        private const int VK_A = 0x41;
        private const int VK_C = 0x43;
        private const uint MOUSEEVENTF_LEFTDOWN = 0x02;
        private const uint MOUSEEVENTF_LEFTUP = 0x04;
        public struct POINT
        {
            public int X;
            public int Y;

            public POINT(int x, int y)
            {
                X = x;
                Y = y;
            }
        }
        private void CtrlA()
        {

        }

        private async Task CaptureMessages()
        {
            List<Task> tasks = new List<Task>();

            foreach (var chatName in ChatName)
            {
                tasks.Add(GetChatMessageFromWindowAsync(chatName));
            }

            await Task.WhenAll(tasks);
        }

        private async Task GetChatMessageFromWindowAsync(string chatterName)
        {
            try
            {
                // 异步获取窗口左上角坐标
                Point windowPoint = await Task.Run(() => WindowHelper.GetWindowTopLeftCorner("QiDian", chatterName));
                IntPtr handleQD = WindowFromPoint(windowPoint);
                // 将窗口置于前台
                //SetForegroundWindow(handleQD);

                // 强制刷新窗口
                //InvalidateRect(handleQD, IntPtr.Zero, true);
                if (windowPoint.X == 0 && windowPoint.Y == 0)
                {
                    AppLog.WriteInfo($"窗体 {chatterName} 在原点（0,0）");
                    // 窗体在原点（0,0）
                }
                else if (windowPoint.X.ToString().Contains("-32000"))
                {
                    AppLog.WriteInfo($"窗体 {chatterName} 没开");
                    // 窗体没开
                }
                else
                {
                    await Task.Run(() => GetMessage(windowPoint, handleQD, chatterName));
                }
            }
            catch (System.Exception ex)
            {
                AppLog.WriteError($"{ex.Message} CheckMsgFromWindow for {chatterName}");
            }
        }

        private int leftPoint = 480;
        private int downPoint = 130;
        [DllImport("user32.dll")]
        private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
        [DllImport("user32.dll")]
        private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, UIntPtr dwExtraInfo);

        InputSimulator simulator = new InputSimulator();
      
        private string GetMessage(Point windowPoint, IntPtr hwnd, string chatName)
        {
            try
            {
                AppLog.WriteInfo($"{chatName}--窗体左上角为：x:{windowPoint.X},y:{windowPoint.Y}！");
                int sendMessageCount = 0;
                int receiveMessageCount = 0;
                int searchStartX = windowPoint.X + leftPoint; // 发送方起始搜索点的 X 坐标
                int searchStartY = windowPoint.Y + downPoint; // 发送方起始搜索点的 Y 坐标
                                                              // Bring the window to the foreground
                 ShowWindow(hwnd, HWND_TOPMOST);
                    SetForegroundWindow(hwnd);                                        //SetForegroundWindow(hwnd);
                int pixelInt = 0;
                    int i = 0;
                    for (int y = searchStartY; y < searchStartY+windowHeight; y += step)
                    {
                        Point temp1 = new Point(searchStartX, y);
                    lock(lock1)
                    {
                        pixelInt = GetColorRGB(temp1);
                    }
                       
                        i++;
                        if (pixelInt == 16777215)
                        {
                            searchStartY = y;
                            AppLog.WriteInfo($"{chatName}--第一个焦点位置-位置在{i}：x:{searchStartX},y:{y}，颜色：{pixelInt}");
                            break;
                        }
                        AppLog.WriteInfo($"{chatName}--第{i}个位置：x:{searchStartX},y:{y}，颜色：{pixelInt}");
                    }

                    var sim = new InputSimulator();
                    // 将屏幕坐标转换为虚拟桌面坐标
                    int virtualScreenX = searchStartX * 65535 / Screen.PrimaryScreen.Bounds.Width;
                    int virtualScreenY = searchStartY * 65535 / Screen.PrimaryScreen.Bounds.Height;

                    // 模拟点击获取焦点
                    sim.Mouse.MoveMouseToPositionOnVirtualDesktop(virtualScreenX, virtualScreenY);
                    sim.Mouse.LeftButtonClick();

                    // 等待点击操作完成
                    Thread.Sleep(500);

                    // 模拟 Ctrl + A 全选
                    sim.Keyboard.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_A);

                    // 等待全选操作完成
                    Thread.Sleep(200);

                    // 模拟 Ctrl + C 复制
                    sim.Keyboard.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_C);

                    // 等待复制操作完成
                    Thread.Sleep(400);

                    // 再次点击取消焦点
                    sim.Mouse.LeftButtonClick();
                     //Thread.Sleep(200);

                string clipboardContent = null;
                    Thread staThread = new Thread(
                                         delegate ()
                                         {
                                             try
                                             {
                                                 // 确保线程在 STA 模式下运行
                                                 if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
                                                 {
                                                     throw new ThreadStateException("The thread must be in STA mode to access the clipboard.");
                                                 }

                                                 // 获取剪贴板的文本内容
                                                 clipboardContent = Clipboard.GetText();
                                                 this.Invoke((Action)(() =>
                                                 {
                                                     this.richTextBox1.Text += clipboardContent;
                                                 }));

                                                 var ParsedMessage = ParseMessages(clipboardContent);
                                             }

                                             catch (Exception ex)
                                             {

                                             }
                                         });
                    staThread.SetApartmentState(ApartmentState.STA);
                    staThread.Start();
                    staThread.Join();
                // 写入文件
                string fileName = $"{chatName}.txt"; // 文件名为 chatName.txt
                string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), fileName); // 保存在桌面上

                using (StreamWriter writer = new StreamWriter(filePath, false)) // false 表示覆盖已存在的文件，true 表示追加到文件末尾
                {
                    writer.Write(clipboardContent);
                }


                //AppLog.WriteInfo("聊天人" + chatName + $"共找到{sendMessageCount}个发送方聊天气泡");





                return "1";
            }
            catch (Exception ex)
            {
                AppLog.WriteError("聊天人" + chatName + ex.Message + "抓取文本异常");
            }
            finally
            {
                ShowWindow(hwnd, HWND_NOTOPMOST);
            }
            return null;
        }
        public static List<Message> ParseMessages(string input)
        {
            List<Message> messages = new List<Message>();
            string[] lines = input.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

            Message currentMessage = null;
            foreach (string line in lines)
            {
                string trimmedLine = line.Trim();
                // Check if the line starts with a sender and timestamp
                if (IsSenderTimestampLine(line)) //判断是时间戳和发送人
                {
                    // If there is an existing message, add it to the list
                    if (currentMessage != null)
                    {
                        messages.Add(currentMessage);
                    }

                    // Create a new message
                    currentMessage = new Message();
                    string[] parts = line.Split(new[] { ' ' }, 3);
                    string timestampPart = parts[2].TrimEnd('\r');  // 去掉 '\r'
                    currentMessage.Sender = parts[0];
                    currentMessage.Timestamp = DateTime.ParseExact($"{parts[1]} {timestampPart}", "yyyy/M/d HH:mm:ss", CultureInfo.InvariantCulture);
                    currentMessage.Content = string.Empty;
                }
                else  //是内容消息（记得区分 引用和非引用）
                {
                    // Append to the current message's content
                    if (currentMessage != null)
                    {
                        if (!string.IsNullOrEmpty(currentMessage.Content))
                        {
                            currentMessage.Content +=line;
                        }
                        else
                        {
                            currentMessage.Content += trimmedLine;
                            // Check if the first line of content indicates a quoted message
                            if (trimmedLine.StartsWith("钟长明")|| trimmedLine.StartsWith("吴忠贤"))
                            {
                                currentMessage.IsQuoted = true;
                            }
                        }
                    }
                }
            }

            // Add the last message if any
            if (currentMessage != null)
            {
                messages.Add(currentMessage);
            }

            return messages;
        }

        private static bool IsSenderTimestampLine(string line)
        {

            string[] parts = line.Split(' ');
            if (parts.Length >= 3)
            {
                DateTime temp;
                bool result = DateTime.TryParseExact($"{parts[1]} {parts[2]}".TrimEnd('\r'), "yyyy/M/d HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out temp);
                return result;
            }
            return false;
        }

        /// <summary>
        /// 测试抓取
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button3_Click(object sender, EventArgs e)
        {
            string chatterName = "钟长明";
            // 异步获取窗口左上角坐标
            Point windowPoint = await Task.Run(() => WindowHelper.GetWindowTopLeftCorner("QiDian", chatterName));
            IntPtr handleQD = WindowFromPoint(windowPoint);
            // 将窗口置于前台
            //SetForegroundWindow(handleQD);

            // 强制刷新窗口
            //InvalidateRect(handleQD, IntPtr.Zero, true);
            if (windowPoint.X == 0 && windowPoint.Y == 0)
            {
                AppLog.WriteInfo($"窗体 {chatterName} 在原点（0,0）");
                // 窗体在原点（0,0）
            }
            else if (windowPoint.X.ToString().Contains("-32000"))
            {
                AppLog.WriteInfo($"窗体 {chatterName} 没开");
                // 窗体没开
            }
            else
            {
                await Task.Run(() => GetMessage(windowPoint, handleQD, chatterName));
            }
        }

        #endregion
        private const int SW_SHOWNORMAL = 1;
        private const int HWND_TOPMOST = -1;  // 将窗口置顶
        private const int HWND_NOTOPMOST = -2;  // 取消窗口置顶
        private void button4_Click(object sender, EventArgs e)
        {
            IntPtr hWnd = WindowHelper.FindWindow(null, windowTitle);
            if (hWnd == IntPtr.Zero)
            {
                hWnd = WindowHelper.FindWindow(null, WindowHelper.getAnotherTitle(windowTitle));
                if (hWnd == IntPtr.Zero)
                {
                    return; // Window not found
                }
            }
            if (hWnd != IntPtr.Zero)
            {
                ShowWindow(hWnd, SW_SHOWNORMAL);
                SetForegroundWindow(hWnd);
                //TextWindows = FindTradeWindow(window);
            }
            else
            {
                return;
            }

            string text = this.richTextBox1.Text;
            //Thread t = new Thread(() => SendMessageToTarget(text));

            Thread t = new Thread(() => GetMessageFromTarget());
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
            t.Join();
        }

        /// <summary>
        /// 测试发送
        /// </summary>
        /// <param name="text"></param>
        private void SendMessageToTarget(string text)
        {
            if(text==null)
            {
                AppLog.WriteError("发送数据为空");
            }
            Clipboard.SetText(text);
            //log.Info("Clipboard SetDataObject:", order.Command, "");
            SendKeys.SendWait("^v");
            Task.Delay(10).Wait();
            //log.Info("Command KeyBoard:", "Ctrl+V", "");
            SendKeys.SendWait("{ENTER}");
            //SendKeys.SendWait("{ENTER}");
        }

        private void GetMessageFromTarget()
        {
            // 模拟 Ctrl+A 全选
            SendKeys.SendWait("^a");
            Task.Delay(100).Wait(); // 等待一小段时间确保全选操作完成

            // 模拟 Ctrl+C 复制
            SendKeys.SendWait("^c");
            Task.Delay(100).Wait(); // 等待一小段时间确保复制操作完成

            // 可选：获取剪贴板中的文本内容
            if (Clipboard.ContainsText())
            {
                string copiedText = Clipboard.GetText();
                MessageBox.Show("Copied text: " + copiedText);
            }
        }


        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    }

    public class WindowMessageInfo
    {
        public int LocX { get; set; }
        public int LocY { get; set; }
        public string Type { get; set; }//S:代表发送端，R：代表接收端
        public DateTime RecordTime { get; set; }//记录时间
    }



}
